using Spine.Unity;
using System.Collections;
using UnityEngine;

namespace Spine.Unity.Examples {
    /// <summary>
    /// Spineboy基础视觉表现控制器
    /// 管理角色动画状态、音效播放和视觉效果
    /// </summary>
    public class SpineboyBeginnerView : MonoBehaviour {
        
        #region Inspector 配置区域
        [Header("核心组件")]
        [Tooltip("角色行为模型组件")]
        public SpineboyBeginnerModel model;
        
        [Tooltip("Spine动画控制器")]
        public SkeletonAnimation skeletonAnimation;

        [Header("动画资源")]
        [Tooltip("奔跑动画资源")]
        public AnimationReferenceAsset run;
        
        [Tooltip("待机动画资源")]
        public AnimationReferenceAsset idle;
        
        [Tooltip("瞄准动画资源")]
        public AnimationReferenceAsset aim;
        
        [Tooltip("射击动画资源")]
        public AnimationReferenceAsset shoot;
        
        [Tooltip("跳跃动画资源")]
        public AnimationReferenceAsset jump;

        [Header("事件配置")]
        [Tooltip("脚步声事件数据")]
        public EventDataReferenceAsset footstepEvent;

        [Header("音频设置")]
        [Tooltip("脚步声音调偏移量")]
        public float footstepPitchOffset = 0.2f;
        
        [Tooltip("枪声音调偏移量")]
        public float gunsoundPitchOffset = 0.13f;
        
        [Tooltip("脚步声源")]
        public AudioSource footstepSource;
        
        [Tooltip("枪声音源")]
        public AudioSource gunSource;
        
        [Tooltip("跳跃音效源")]
        public AudioSource jumpSource;

        [Header("粒子效果")]
        [Tooltip("枪口粒子特效")]
        public ParticleSystem gunParticles;
        #endregion

        private SpineBeginnerBodyState previousViewState;

        /// <summary>
        /// 初始化组件订阅
        /// </summary>
        void Start () {
            if (skeletonAnimation == null) return;
            
            // 订阅模型事件
            model.ShootEvent += PlayShoot;
            model.StartAimEvent += StartPlayingAim;
            model.StopAimEvent += StopPlayingAim;
            
            // 订阅动画事件
            skeletonAnimation.AnimationState.Event += HandleEvent;
        }

        /// <summary>
        /// 处理Spine动画事件
        /// </summary>
        /// <param name="trackEntry">动画轨道条目</param>
        /// <param name="e">动画事件数据</param>
        void HandleEvent (Spine.TrackEntry trackEntry, Spine.Event e) {
            if (e.Data == footstepEvent.EventData)
                PlayFootstepSound();  // 触发脚步声播放
        }

        /// <summary>
        /// 每帧更新角色表现
        /// </summary>
        void Update () {
            if (skeletonAnimation == null || model == null) return;

            // 检测角色朝向变化
            if ((skeletonAnimation.skeleton.ScaleX < 0) != model.facingLeft) {
                Turn(model.facingLeft);
            }

            // 处理动画状态切换
            SpineBeginnerBodyState currentModelState = model.state;
            
            // 检查状态是否切换
            if (previousViewState != currentModelState) {
                PlayNewStableAnimation();
            }
            
            previousViewState = currentModelState;
        }

        /// <summary>
        /// 播放稳定状态动画
        /// </summary>
        void PlayNewStableAnimation () {
            SpineBeginnerBodyState newModelState = model.state;
            Animation nextAnimation;

            // 跳跃结束状态处理
            if (previousViewState == SpineBeginnerBodyState.Jumping && 
                newModelState != SpineBeginnerBodyState.Jumping) {
                PlayFootstepSound();  // 落地播放脚步声
            }

            // 起跳
            if (newModelState == SpineBeginnerBodyState.Jumping) {
                jumpSource.Play();
                nextAnimation = jump;
            } 
            else // 跑步，行走
            {
                nextAnimation = (newModelState == SpineBeginnerBodyState.Running) 
                    ? run : idle;
            }

            // 在轨道0播放主动画
            skeletonAnimation.AnimationState.SetAnimation(0, nextAnimation, true);
        }

        /// <summary>
        /// 播放脚步声效
        /// </summary>
        void PlayFootstepSound () {
            footstepSource.pitch = GetRandomPitch(footstepPitchOffset);
            footstepSource.Play();
        }

        /// <summary>
        /// 调试动画轨道状态
        /// </summary>
        [ContextMenu("Check Tracks")]
        void CheckTracks () {
            AnimationState state = skeletonAnimation.AnimationState;
            Debug.Log($"轨道0: {state.GetCurrent(0)}");
            Debug.Log($"轨道1: {state.GetCurrent(1)}");
        }

        #region 动作控制
        /// <summary>
        /// 播放射击动画序列
        /// </summary>
        public void PlayShoot () {
            // 主射击动画（轨道1）
            TrackEntry shootTrack = skeletonAnimation.AnimationState.SetAnimation(1, shoot, false);
            ConfigureTrack(shootTrack);

            // 瞄准动画（轨道2）
            TrackEntry aimTrack = skeletonAnimation.AnimationState.SetAnimation(2, aim, false);
            ConfigureTrack(aimTrack);

            // 播放音效和粒子
            gunSource.pitch = GetRandomPitch(gunsoundPitchOffset);
            gunSource.Play();
            gunParticles.Play();
        }

        /// <summary>
        /// 开始瞄准动画
        /// </summary>
        public void StartPlayingAim () {
            skeletonAnimation.AnimationState.SetAnimation(2, aim, true);
            ConfigureTrack(skeletonAnimation.AnimationState.GetCurrent(2));
        }

        /// <summary>
        /// 停止瞄准动画
        /// </summary>
        public void StopPlayingAim () {
            skeletonAnimation.state.AddEmptyAnimation(2, 0.5f, 0.1f);
        }

        /// <summary>
        /// 角色转向控制
        /// </summary>
        /// <param name="facingLeft">是否面朝左侧</param>
        public void Turn (bool facingLeft) {
            skeletonAnimation.Skeleton.ScaleX = facingLeft ? -1f : 1f;
            // 可扩展：添加转身过渡动画
        }
        #endregion

        #region 工具方法
        /// <summary>
        /// 配置动画轨道参数
        /// </summary>
        /// <param name="track">动画轨道条目</param>
        void ConfigureTrack(TrackEntry track) {
            track.MixAttachmentThreshold = 1f; // 混合阈值 -- 影响新旧动画混合效果
            track.SetMixDuration(0f, 0f); // 混合动画播放时间，混合动画延迟时间
        }

        /// <summary>
        /// 生成随机音调偏移
        /// </summary>
        /// <param name="maxOffset">最大偏移量</param>
        /// <returns>调整后的音调值</returns>
        public float GetRandomPitch (float maxPitchOffset) {
            return 1f + Random.Range(-maxPitchOffset, maxPitchOffset);
        }
        #endregion
    }
}